package com.idanchuang.count.support;

import com.idanchuang.count.core.model.BizConfig;
import com.idanchuang.count.core.model.BizProperties;
import com.idanchuang.count.core.util.keyformat.UserCountKeysFormatter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.idanchuang.count.core.constant.CountConstants.UID_SET_VALUE;

/**
 * 对计数更新命令做校验
 * @author Richard_yyf
 * @version 1.0 2021/5/28
 */
@Component
public class UserCountChecker {

    @Resource(name = "stringRedisTemplate")
    private StringRedisTemplate strTemplate;

    @Resource
    private BizProperties bizProperties;

    /**
     * 幂等键失效时间，秒
     * 默认 10分钟
     */
    @Value("${count.update.idempotent-expire:600}")
    private Long countCommandIdempotentExpire;

    /**
     * 幂等校验
     * @param uid 唯一id
     * @return return true when msg consumed
     */
    public boolean checkUidExist(String uid, String bizCode) {
        if (bizProperties.getSingleConfig(bizCode).isUidCheckEnabled()) {
            // 不会为空，只有在事务和pipeline的时候会返回null
            // 看设置幂等键是否成功，如果不成功return false，说明UidExist return true
            return !Objects.requireNonNull(strTemplate.opsForValue().setIfAbsent(UserCountKeysFormatter.formatUidKey(uid), UID_SET_VALUE, countCommandIdempotentExpire, TimeUnit.SECONDS));
        } else {
            // 幂等开关是关闭的，直接返回false
            return false;
        }

    }

//    public boolean checkTimeLegal(long timestamp, String bizCode) {
//        BizConfig bizConfig = bizProperties.getSingleConfig(bizCode);
//        if (bizConfig.getDivideTime() == null) {
//            return true;
//        }
//        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
//        long startOfDay = LocalDate.now(zoneId).atStartOfDay(zoneId).toInstant().toEpochMilli();
//        // 分界时间点：当天0点 + divideTime（单位:s）
//        long divideTime = startOfDay + bizConfig.getDivideTime() * 1000;
//        return timestamp > divideTime;
//    }

}
